using BepuUtilities;
using System;
using System.Collections.Generic;

namespace DemoContentLoader
{
    public struct CharacterData
    {
        /// <summary>
        /// 字体距离图集中字符字形的最小位置,以图集纹理为单位测量。
        /// (0,0)对应于贴图集的左上角,而不是左上角纹理单元的中心。
        /// </summary>
        public Int2 SourceMinimum;
        /// <summary>
        /// 字体距离图集中字形的宽度和高度,以图集纹理为单位测量。
        /// </summary>
        public Int2 SourceSpan;
        /// <summary>
        /// 从起始笔位置到图片集纹理元素中字形目标渲染位置左上角的偏移量。
        /// </summary>
        public Int2 Bearing;
        /// <summary>
        /// 在此字符上移动时水平笔位置的变化,以贴图集纹理元素为单位测量。不包括任何字距调整。
        /// </summary>
        public int Advance;
        /// <summary>
        /// 应用于从字形纹理数据采样以将其转换为纹理单位的距离的比例因子。
        /// </summary>
        public float DistanceScale;
    }

    public struct CharacterPair : IEquatable<CharacterPair>
    {
        public readonly char A;
        public readonly char B;

        public CharacterPair(char a, char b)
        {
            A = a;
            B = b;
        }

        // 秩序很重要！
        public bool Equals(CharacterPair other)
        {
            return A == other.A && B == other.B;
        }

        public override int GetHashCode()
        {
            return (A * 7919) ^ (B * 6263);
        }

        public override string ToString()
        {
            return "{" + A + ", " + B + "}";
        }
    }
    public class FontContent : IContent
    {
        public int GlyphCount { get; private set; }
        public Texture2DContent Atlas { get; private set; }
        public string Name { get; private set; }
        public float InverseSizeInTexels { get; private set; }
        public Dictionary<char, CharacterData> Characters { get; private set; }

        public ContentType ContentType { get { return ContentType.Font; } }

        internal Dictionary<CharacterPair, int> kerning;

        public FontContent(Texture2DContent atlas, string name, float inverseSizeInTexels,
            Dictionary<char, CharacterData> characterData, Dictionary<CharacterPair, int> kerningTable)
        {
            GlyphCount = GlyphCount;
            Atlas = atlas;
            Name = name;
            InverseSizeInTexels = inverseSizeInTexels;
            Characters = characterData;
            kerning = kerningTable;
        }

        public int GetKerningInTexels(char a, char b)
        {
            if (kerning.TryGetValue(new CharacterPair(a, b), out var pairKerning))
            {
                return pairKerning;
            }
            return 0;
        }
    }
}
